/**
 * Copyright ©2003~2019年5月5日 szkingdom
 * @author raohj
 * @date 2019年5月5日
 * @file RCyclicBarrier.java
 * @comment : please input your comment to this file
 * @version : input version
 * @modify:
 * 		1、 2019年5月5日 由 raohj 新建文件
 */
package com.ccnu.demojava.concurrent.tools;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author raohj
 * @date 2019年5月5日
 * @version 
 * @comment 测试CyclicBarrier进行并发任务分解
 *  所有的子任务在调用await时，将进行堵塞。直到最后一个子任务调用完await，并唤醒其他的任务
 */
public class RCyclicBarrier {
	private static final Logger log = LoggerFactory.getLogger(RCyclicBarrier.class);
	
	public static class Horse implements Runnable{
		private static CyclicBarrier cb;
		/**
		 * @param cb 设置线程同步辅助类
		 */
		public Horse(CyclicBarrier cb) {
			this.cb = cb;
		}
		@Override
		public void run() {
			try {
				log.info("[" + Thread.currentThread().threadId() +"]开始执行分解任务");
				Thread.sleep(1000);
				cb.await();	// 通知任务完成
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (BrokenBarrierException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static class HorseRace{
		private CyclicBarrier cb;
		private static ExecutorService es = Executors.newFixedThreadPool(200);
		/**
		 * @param nRaskCnt 任务分解的个数
		 * @comment 
		 */
		public HorseRace(int nRaskCnt) {
			// 预先设置需要分解的任务数
			cb = new CyclicBarrier(nRaskCnt, new Runnable() {
				@Override
				public void run() {
					log.info("所有分解任务执行完毕");
				}
			});
			
			for(int i=0; i<nRaskCnt; i++) {
				Horse hs = new Horse(cb);
				es.execute(hs);
			}
		}
	}
	
	public static void test() {
		HorseRace hr = new HorseRace(2);
	}
}
